package aidevelopment;

import ui.OthelloUserInterface;

public class Spel {

	private int beurtNummer;
	private Bord bord;
	private BeurtRij beurtRij;
	private long beginTijd;
	private int hoogte;
	private int breedte;
	private int maxAantalBeurten;

	Spel(int hoogte,int breedte,int maxAantalBeurten){
		beurtNummer = 0;
		bord = new Bord(hoogte,breedte);
		beurtRij = new BeurtRij(maxAantalBeurten);
		this.breedte = breedte;
		this.hoogte = hoogte;
		this.maxAantalBeurten = maxAantalBeurten;


		bord.voegToe(3, 3, OthelloUserInterface.WIT);
		bord.voegToe(4, 4, OthelloUserInterface.WIT);
		bord.voegToe(3, 4, OthelloUserInterface.ZWART);
		bord.voegToe(4, 3, OthelloUserInterface.ZWART);
	}

	Spel(int hoogte,int breedte,int maxAantalBeurten,Bord bord,BeurtRij beurtRij){
		beurtNummer = 0;
		this.bord = bord;
		this.beurtRij = beurtRij;
		this.breedte = breedte;
		this.hoogte = hoogte;
		this.maxAantalBeurten = maxAantalBeurten;


		bord.voegToe(3, 3, OthelloUserInterface.WIT);
		bord.voegToe(4, 4, OthelloUserInterface.WIT);
		bord.voegToe(3, 4, OthelloUserInterface.ZWART);
		bord.voegToe(4, 3, OthelloUserInterface.ZWART);
	}

	public Spel kopie(){
		Spel kopie = new Spel(hoogte,breedte,maxAantalBeurten,bord,beurtRij);
		return kopie;

	}

	public String schrijfBeurtCode(int nummer){
		String resultaat = geefSpelerNaam(nummer);
		resultaat += "\t";
		resultaat += beurtRij.geefBeurt(nummer).geefTijd();
		resultaat += "\t";
		resultaat += beurtRij.geefBeurt(nummer).geefZetInTekst();
		resultaat += " ";
		if(beurtRij.geefBeurt(nummer).geefZet()){
			resultaat += schrijfCoordinaat(beurtRij.geefBeurt(nummer).geefZetInhoud().geefZetCoordinaat());
			for(int i = 0; i<beurtRij.geefBeurt(nummer).geefZetInhoud().geefVeranderdeStenen().geefAantalCoordinaten(); i++){
				resultaat += " ";
				resultaat += schrijfCoordinaat(beurtRij.geefBeurt(nummer).geefZetInhoud().geefVeranderdeStenen().geefCoordinaten()[i]);
			}
			resultaat += "\n";
			return resultaat;
		} else {
			resultaat += "\n";
			return resultaat;
		}
		
	}

	public String schrijfCoordinaat(Coordinaat coordinaat){
		char x = (char)(coordinaat.geefX() + 'a');
		int y = coordinaat.geefY() + 1;
		return new String(x + " " + y);
	}

	public void zetTijd(){
		beginTijd = System.currentTimeMillis();
	}


	public boolean doorgaan(){
		if(checkMogelijkeZetten(OthelloUserInterface.WIT).geefAantalCoordinaten() == 0 && checkMogelijkeZetten(OthelloUserInterface.ZWART).geefAantalCoordinaten() == 0){
			return false;
		} else{
			return true;
		}
	}

	public String bepaalWinnaar(){
		int wit = 0;
		int zwart = 0;
		int leeg = 0;
		for(int i = 0;i < bord.geefLengte();i++){
			for(int j = 0;j < bord.geefHoogte();j++){
				if(bord.geefWaarde(i, j) == OthelloUserInterface.WIT){
					wit += 1;
				} else if(bord.geefWaarde(i, j) == OthelloUserInterface.ZWART){
					zwart += 1;
				} else if(bord.geefWaarde(i, j) == OthelloUserInterface.LEEG){
					leeg += 1;
				} else{
					return new String("fout!!!");
				}
			}
		}
		if(wit>zwart){
			return new String("Wit");
		} else{
			return new String("Zwart");
		}
	}

	public int telKleur(int kleur){
		int teller = 0;
		for(int i = 0;i < bord.geefLengte();i++){
			for(int j = 0;j < bord.geefHoogte();j++){
				if(bord.geefWaarde(i, j) == kleur){
					teller += 1;
				}
			}
		}
		return teller;
	}

	public int geefBeurtNummer(){
		return beurtNummer;
	}

	public Zet geefZet(){
		return beurtRij.geefBeurt(beurtNummer - 1).geefZetInhoud();
	}

	public Bord geefBord(){
		return bord;
	}

	public int geefKleur(){
		if((beurtNummer % 2) == 0){
			return OthelloUserInterface.ZWART;
		} else if((beurtNummer % 2) == 1){
			return OthelloUserInterface.WIT;
		} else {
			return OthelloUserInterface.LEEG;
		}
	}

	public int geefInverseKleur(int kleur){
		if(kleur == OthelloUserInterface.ZWART)			return OthelloUserInterface.WIT;
		else if (kleur == OthelloUserInterface.LEEG)	return OthelloUserInterface.LEEG;
		else 											return OthelloUserInterface.ZWART;

	}

	public String geefSpelerNaam(){
		if((beurtNummer % 2) == 0){
			return new String("zwart");
		} else if((beurtNummer % 2) == 1){
			return new String("wit");
		} else {
			return new String("fout");
		}
	}

	public String geefSpelerNaam(int i){
		if((i % 2) == 0){
			return new String("zwart");
		} else if((i % 2) == 1){
			return new String("wit");
		} else {
			return new String("fout");
		}
	}

	public String doeZet(Coordinaat coordinaat){
		CoordinaatRij veranderdeStenen = checkTussenliggendeStenen(coordinaat,geefKleur());
		Zet zet = new Zet(coordinaat,veranderdeStenen);
		int tijd = (int)(System.currentTimeMillis() - beginTijd);
		Beurt beurt = new Beurt(true,geefKleur(),tijd,zet);
		beurtRij.voegBeurtToe(beurt);
		zetZetOpBord(zet);
		String mededeling =  new String("Speler " + geefSpelerNaam() + " zette een steen op (" + coordinaat.geefX() + "," + 
				coordinaat.geefY() + ") en sloeg daarmee " + veranderdeStenen.geefAantalCoordinaten() +" stenen!\n");
		beurtNummer += 1;
		zetTijd();
		return mededeling;
	}

	public String doePas(){
		int tijd = (int)(System.currentTimeMillis() - beginTijd);
		Beurt beurt = new Beurt(false,geefKleur(),tijd);
		beurtRij.voegBeurtToe(beurt);
		String mededeling =  new String("Speler " + geefSpelerNaam() + " heeft gepast!\n");
		beurtNummer += 1;
		zetTijd();
		return mededeling;
	}

	public void zetZetOpBord(Zet zet){
		int kleur = geefKleur();
		bord.voegToe(zet.geefZetCoordinaat(), kleur);
		plaatsCoordinaatRij(zet.geefVeranderdeStenen(),kleur);
	}

	public void plaatsCoordinaatRij(CoordinaatRij coordinaatRij, int kleur){
		for(int i = 0; i<coordinaatRij.geefAantalCoordinaten();i++){
			bord.voegToe(coordinaatRij.geefCoordinaten()[i], kleur);
		}
	}

	public void gaZetTerug(){
		beurtNummer -= 1;
		Zet zet = beurtRij.geefBeurt(beurtNummer).geefZetInhoud();
		bord.voegToe(zet.geefZetCoordinaat(),OthelloUserInterface.LEEG);
		plaatsCoordinaatRij(zet.geefVeranderdeStenen(),geefInverseKleur(geefKleur()));
	}


	public CoordinaatRij checkMogelijkeZetten(int kleur){
		CoordinaatRij resultaat = new CoordinaatRij(hoogte*breedte);
		for(int i = 0;i < breedte;i++){
			for(int j = 0;j < hoogte;j++){
				if(bord.geefWaarde(i, j) == OthelloUserInterface.LEEG){
					if(checkTussenliggendeStenen(new Coordinaat(i,j),kleur).geefAantalCoordinaten() > 0){
						resultaat.voegToe(new Coordinaat(i,j));
					}
				}
			}
		}
		return resultaat;
	}

	public CoordinaatRij checkMogelijkeZetten(){
		int kleur = geefKleur();
		CoordinaatRij resultaat = new CoordinaatRij(hoogte*breedte);
		for(int i = 0;i < breedte;i++){
			for(int j = 0;j < hoogte;j++){
				if(bord.geefWaarde(i, j) == OthelloUserInterface.LEEG){
					if(checkTussenliggendeStenen(new Coordinaat(i,j),kleur).geefAantalCoordinaten() > 0){
						resultaat.voegToe(new Coordinaat(i,j));
					}
				}
			}
		}
		return resultaat;
	}

	public CoordinaatRij checkTussenliggendeStenen(Coordinaat klik,int kleur){
		CoordinaatRij tussenliggendeStenen = new CoordinaatRij(hoogte*breedte);
		if(bord.geefWaarde(klik) == OthelloUserInterface.LEEG){
			for(int i = 0;i < Richting.RICHTINGEN.length;i++){
				CoordinaatRij tmpCR = checkRichting(i,klik,kleur);
				tussenliggendeStenen.voegCoordinaatRijToe(tmpCR);
			}
		}
		return tussenliggendeStenen;
	}

	public CoordinaatRij checkRichting(int i,Coordinaat klikBackup,int kleur){
		CoordinaatRij tussenliggendEenRichting = new CoordinaatRij(hoogte*breedte);
		Coordinaat klik = new Coordinaat(klikBackup.geefX(),klikBackup.geefY());


		klik.transleer(Richting.RICHTINGEN[i]);
		while(klik.geefX() < breedte 		&& klik.geefY() < hoogte 
				&& 	klik.geefX() >= 0 		&& klik.geefY() >= 0){

			int kleurCheck = bord.geefWaarde(klik);
			if(kleurCheck == geefInverseKleur(kleur)){
				tussenliggendEenRichting.voegToe(new Coordinaat(klik.geefX(), klik.geefY()));
			}
			else if(kleurCheck == kleur){
				if(tussenliggendEenRichting.geefAantalCoordinaten() > 0){
					return tussenliggendEenRichting;
				}
				else{
					return new CoordinaatRij(0);
				}
			}
			else if(kleurCheck == OthelloUserInterface.LEEG){
				return new CoordinaatRij(0);
			}
			klik.transleer(Richting.RICHTINGEN[i]);
		}
		return new CoordinaatRij(0);

	}



}
